<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2009, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter Compatibility Helpers
 *
 * This helper contains some functions based on the PEAR PHP_Compat library
 * http://pear.php.net/package/PHP_Compat
 *
 * The PEAR compat library is a little bloated and the code doesn't harmonize
 * well with CodeIgniter, so those functions have been refactored.
 * We cheat a little and use CI's _exception_handler() to output our own PHP errors
 * so that the behavior fully mimicks the PHP 5 counterparts.  -- Derek Jones
 *
 * @package		CodeIgniter
 * @subpackage	Helpers
 * @category	Helpers
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/helpers/compatibility_helper.html
 */

// ------------------------------------------------------------------------

if ( ! defined('PHP_EOL')) {
  define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
}

// ------------------------------------------------------------------------

/**
 * file_put_contents()
 *
 * Writes a string to a file
 * http://us.php.net/manual/en/function.file_put_contents.php
 * argument 4, $context, not supported
 *
 * @access	public
 * @param	string		file name
 * @param	mixed		data to be written
 * @param	int			flags
 * @return	int			length of written string
 */
if ( ! function_exists('file_put_contents')) {
  function file_put_contents($filename, $data, $flags = NULL) {
    if (is_scalar($data)) {
      settype($data, 'STRING');
    }

    if ( ! is_string($data) && ! is_array($data) && ! is_resource($data)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    // read stream if given a stream resource
    if (is_resource($data)) {
      if (get_resource_type($data) !== 'stream') {
        $backtrace = debug_backtrace();
        _exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
        return FALSE;
      }

      $text = '';

      while ( ! feof($data)) {
        $text .= fread($data, 4096);
      }

      $data = $text;
      unset($text);
    }

    // strings only please!
    if (is_array($data)) {
      $data = implode('', $data);
    }

    // Set the appropriate mode
    if (($flags & 8) > 0) // 8 = FILE_APPEND flag
    {
      $mode = FOPEN_WRITE_CREATE;
    }
    else {
      $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
    }

    // Check if we're using the include path
    if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
    {
      $use_include_path = TRUE;
    }
    else {
      $use_include_path = FALSE;
    }

    $fp = @fopen($filename, $mode, $use_include_path);

    if ($fp === FALSE) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    if (($flags & LOCK_EX) > 0) {
      if ( ! flock($fp, LOCK_EX)) {
        $backtrace = debug_backtrace();
        _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
        return FALSE;
      }
    }

    // write it
    if (($written = @fwrite($fp, $data)) === FALSE) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
    }

    // Close the handle
    @fclose($fp);

    // Return length
    return $written;
  }
}

// ------------------------------------------------------------------------

/**
 * fputcsv()
 *
 * Format line as CSV and write to file pointer
 * http://us.php.net/manual/en/function.fputcsv.php
 *
 * @access	public
 * @param	resource	file pointer
 * @param	array		data to be written
 * @param	string		delimiter
 * @param	string		enclosure
 * @return	int			length of written string
 */
if ( ! function_exists('fputcsv')) {
  function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"') {
  // Checking for a handle resource
    if ( ! is_resource($handle)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    // OK, it is a resource, but is it a stream?
    if (get_resource_type($handle) !== 'stream') {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    // Checking for an array of fields
    if ( ! is_array($fields)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    // validate delimiter
    if (strlen($delimiter) > 1) {
      $delimiter = substr($delimiter, 0, 1);
      $backtrace = debug_backtrace();
      _exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
    }

    // validate enclosure
    if (strlen($enclosure) > 1) {
      $enclosure = substr($enclosure, 0, 1);
      $backtrace = debug_backtrace();
      _exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);

    }

    $out = '';

    foreach ($fields as $cell) {
      $cell = str_replace($enclosure, $enclosure.$enclosure, $cell);

      if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE) {
        $out .= $enclosure.$cell.$enclosure.$delimiter;
      }
      else {
        $out .= $cell.$delimiter;
      }
    }

    $length = @fwrite($handle, substr($out, 0, -1)."\n");

    return $length;
  }
}

// ------------------------------------------------------------------------

/**
 * stripos()
 *
 * Find position of first occurrence of a case-insensitive string
 * http://us.php.net/manual/en/function.stripos.php
 *
 * @access	public
 * @param	string		haystack
 * @param	string		needle
 * @param	int			offset
 * @return	int			numeric position of the first occurrence of needle in the haystack
 */
if ( ! function_exists('stripos')) {
  function stripos($haystack, $needle, $offset = NULL) {
  // Cast non string scalar values
    if (is_scalar($haystack)) {
      settype($haystack, 'STRING');
    }

    if ( ! is_string($haystack)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    if ( ! is_scalar($needle)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    if (is_float($offset)) {
      $offset = (int)$offset;
    }

    if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
      return NULL;
    }

    return strpos(strtolower($haystack), strtolower($needle), $offset);
  }
}

// ------------------------------------------------------------------------

/**
 * str_ireplace()
 *
 * Find position of first occurrence of a case-insensitive string
 * http://us.php.net/manual/en/function.str-ireplace.php
 * (parameter 4, $count, is not supported as to do so in PHP 4 would make
 * it a required parameter)
 *
 * @access	public
 * @param	mixed		search
 * @param	mixed		replace
 * @param	mixed		subject
 * @return	int			numeric position of the first occurrence of needle in the haystack
 */
if ( ! function_exists('str_ireplace')) {
  function str_ireplace($search, $replace, $subject) {
  // Nothing to do here
    if ($search === NULL OR $subject === NULL) {
      return $subject;
    }

    // Crazy arguments
    if (is_scalar($search) && is_array($replace)) {
      $backtrace = debug_backtrace();

      if (is_object($replace)) {
        show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
      }
      else {
        _exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
      }
    }

    // Searching for an array
    if (is_array($search)) {
    // Replacing with an array
      if (is_array($replace)) {
        $search = array_values($search);
        $replace = array_values($replace);

        if (count($search) >= count($replace)) {
          $replace = array_pad($replace, count($search), '');
        }
        else {
          $replace = array_slice($replace, 0, count($search));
        }
      }
      else {
      // Replacing with a string all positions
        $replace = array_fill(0, count($search), $replace);
      }
    }
    else {
    //Searching for a string and replacing with a string.
      $search  = array((string)$search);
      $replace = array((string)$replace);
    }

    // Prepare the search array
    foreach ($search as $search_key => $search_value) {
      $search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
    }

    // Prepare the replace array (escape backreferences)
    foreach ($replace as $k => $v) {
      $replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
    }

    // do the replacement
    $result = preg_replace($search, $replace, (array)$subject);

    // Check if subject was initially a string and return it as a string
    if ( ! is_array($subject)) {
      return current($result);
    }

    // Otherwise, just return the array
    return $result;
  }
}

// ------------------------------------------------------------------------

/**
 * http_build_query()
 *
 * Generate URL-encoded query string
 * http://us.php.net/manual/en/function.http-build-query.php
 *
 * @access	public
 * @param	array		form data
 * @param	string		numeric prefix
 * @param	string		argument separator
 * @return	string		URL-encoded string
 */
if ( ! function_exists('http_build_query')) {
  function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL) {
  // Check the data
    if ( ! is_array($formdata) && ! is_object($formdata)) {
      $backtrace = debug_backtrace();
      _exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);
      return FALSE;
    }

    // Cast it as array
    if (is_object($formdata)) {
      $formdata = get_object_vars($formdata);
    }

    // If the array is empty, return NULL
    if (empty($formdata)) {
      return NULL;
    }

    // Argument separator
    if ($separator === NULL) {
      $separator = ini_get('arg_separator.output');

      if (strlen($separator) == 0) {
        $separator = '&';
      }
    }

    // Start building the query
    $tmp = array();

    foreach ($formdata as $key => $val) {
      if ($val === NULL) {
        continue;
      }

      if (is_integer($key) && $numeric_prefix != NULL) {
        $key = $numeric_prefix.$key;
      }

      if (is_resource($val)) {
        return NULL;
      }

      // hand it off to a recursive parser
      $tmp[] = _http_build_query_helper($key, $val, $separator);
    }

    return implode($separator, $tmp);
  }


  // Helper helper.  Remind anyone of college?
  // Required to handle recursion in nested arrays.
  //
  // You could shave fractions of fractions of a second by moving where
  // the urlencoding takes place, but it's much less intuitive, and if
  // your application has 10,000 form fields, well, you have other problems ;)
  function _http_build_query_helper($key, $val, $separator = '&') {
    if (is_scalar($val)) {
      return urlencode($key).'='.urlencode($val);
    }
    else {
    // arrays please
      if (is_object($val)) {
        $val = get_object_vars($val);
      }

      foreach ($val as $k => $v) {
        $tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
      }
    }

    return implode($separator, $tmp);
  }
}


/* End of file compatibility_helper.php */
/* Location: ./system/helpers/compatibility_helper.php */